package main

import (
	"fmt"
	"reflect"
)

// map是一种无序的键值对的集合。
// map最重要的一点是通过key来快速检索数据，key类似于索引，指向数据的值。
// 键类型必须定义操作 == 和 !=，例如 string、int、float。
// 因此数组、切片和结构不能用作键类型，但指针和接口类型可以。

// 声明map
// map 是引用类型，声明后需要使用 make 函数初始化才能使用。
// 语法：var mapName map[keyType]valueType
// mapName 是 map 的名称，keyType 是键的类型，valueType 是值的类型。

// 初始化map
// 语法：make(map[keyType]valueType)

func main() {
	x := map[string]int{"Kate": 28, "John": 37, "Raj": 20}

	type Vertex struct {
		X, Y float64
	}

	fmt.Println(x)         // map[John:37 Kate:28 Raj:20]
	fmt.Println(x["Kate"]) // 28

	// 遍历map
	for key, value := range x {
		fmt.Println(key, value)
	}

	// 添加map元素
	x["Tom"] = 25

	// 修改map元素
	x["John"] = 38

	// 删除map元素
	delete(x, "John")
	fmt.Println(x)

	// 检查map中是否存在某个键
	value, ok := x["Tom"]
	if ok {
		fmt.Printf("Tom is: %v\n", value)
	} else {
		fmt.Println("Tom is not in the map")
	}

	v, ok := x["ketty"]
	fmt.Println("The value:", v, "Present?", ok)

	// 获取map的长度
	fmt.Println(len(x))

	// 清空map
	x = make(map[string]int)
	fmt.Println(len(x))

	var m = map[string]Vertex{
		"Bell Labs": {40.68433, -74.39967},
		"Google":    {37.42202, -122.08408},
	}
	fmt.Println(m)
	notExistVertext, ok := m["Bell"]        // 检查键是否存在 | 获取值
	fmt.Println(notExistVertext)            // {0 0}
	someVertex, ok := m["Bell Labs"]        // 检查键是否存在 | 获取值
	fmt.Println(someVertex)                 // {40.68433 -74.39967}
	fmt.Println(reflect.TypeOf(someVertex)) // main.Vertex
	fmt.Println(someVertex.Y)               // -74.39967
}
